#include "Timestamp.h"
#include <stdio.h>
#if defined(_WIN32) || defined(_WIN64)
  #include <windows.h>
  #include <time.h>
#ifdef _MSC_VER
#pragma warning(disable:4244 4996) // for conversion from 'time_t' to 'long' and _snprintf
#endif
using namespace std;
namespace {
int gettimeofday(struct timeval *tp, void *tzp) {
    time_t clock;
    struct tm tm;
    SYSTEMTIME wtm;
    GetLocalTime(&wtm);
    tm.tm_year = wtm.wYear - 1900;
    tm.tm_mon  = wtm.wMonth - 1;
    tm.tm_mday = wtm.wDay;
    tm.tm_hour = wtm.wHour;
    tm.tm_min  = wtm.wMinute;
    tm.tm_sec  = wtm.wSecond;
    tm.tm_isdst = -1;
    clock = mktime(&tm);
    tp->tv_sec = clock;
    tp->tv_usec = wtm.wMilliseconds * 1000;
    //struct tm * temp = localtime(&clock);
    //char * tmp = asctime(temp);
    return (0);
}
} // namespace

#else // POSIX
  #include <sys/time.h>
  #define __STDC_FORMAT_MACROS
  #include <inttypes.h>
  #undef __STDC_FORMAT_MACROS
#endif

namespace dsth {

string Timestamp::ToString() const {
    char buf[32] = {0};
    int64_t seconds = micro_second_ / kMicroSecondsPerSecond;
    int64_t microseconds = micro_second_ % kMicroSecondsPerSecond;
    snprintf(buf, sizeof(buf)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds);
    return buf;
}

string Timestamp::ToFomattedString() const {
    char buf[32] = {0};
    time_t seconds = static_cast<time_t>(micro_second_ / kMicroSecondsPerSecond);
    int microseconds = static_cast<int>(micro_second_ % kMicroSecondsPerSecond);
    struct tm *tm_time;
    tm_time = localtime(&seconds);

    snprintf(buf, sizeof(buf), "%4d-%02d-%02d %02d:%02d:%02d.%06d",
        tm_time->tm_year + 1900, tm_time->tm_mon + 1, tm_time->tm_mday,
        tm_time->tm_hour, tm_time->tm_min, tm_time->tm_sec,
        microseconds);
    return buf;
}

Timestamp Timestamp::GetNowTime() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    int64_t seconds = tv.tv_sec;
    return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}

} // namespace
